import { Component, OnInit, Inject } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { FormControl } from '@angular/forms';
import { DateAdapter } from '@angular/material/core';
import { RestService } from '../../services/rest.service';
import { TranslateService } from '@ngx-translate/core';

import * as _ from 'lodash';

@Component({
  selector: 'app-person-details',
  templateUrl: './person-details.component.html',
  styleUrls: ['./person-details.component.css']
})
export class PersonDetailsComponent implements OnInit {
  contentHeight = '75vh';
  person: any;

  fromTime;
  fromTimeCtrl = new FormControl(new Date());
  toTime;
  toTimeCtrl = new FormControl(new Date());
  error = '';

  chartOptions;
  echartsInstance;

  bchartOptions;
  bechartsInstance;

  hchartOptions;
  hechartsInstance;

  // For HIST_MOVE, move count per hour
  moveChartOptions;
  moveChartsInstance;

  awayAlarmChartOptions;
  awayAlarmChartsInstance;

  sideAlarmChartOptions;
  sideAlarmChartsInstance;

  upAlarmChartOptions;
  upAlarmChartsInstance;

  breatheAlarmChartOptions;
  breatheAlarmChartsInstance;

  heartAlarmChartOptions;
  heartAlarmChartsInstance;

  wetAlarmChartOptions;
  wetAlarmChartsInstance;

  turnOverAlarmChartOptions;
  turnOverAlarmChartsInstance;

  sleepChartOptions;
  sleepChartsInstance;

  constructor(@Inject(MAT_DIALOG_DATA) private dialogData: any,
              public dialogRef: MatDialogRef<PersonDetailsComponent>,
              private adapter: DateAdapter<any>,
              private translate: TranslateService,
              private rest: RestService,
              private dialog: MatDialog) {
    switch (this.translate.currentLang) {
    case 'en':
      this.adapter.setLocale('en');
      break;
    case 'zh':
      this.adapter.setLocale('zh-CN');
      break;
    case 'tw':
    default:
      this.adapter.setLocale('zh-TW');
      break;
    }

    this.person = dialogData.person;
    this.initChart();
  }

  initChart() {
    const options = {
      title: {
        x: 'left',
        y: 'top',
        text: '',
        subtext: '',
        subtextStyle: {color: 'black'},
      },
      tooltip : {
        trigger: 'item',
        axisPointer: {
          animation: false
        },
        formatter: (params) => {
          return this.translate.get('alarmingStarts')['value'] + ': ' + new Date(params.data[0]).toLocaleString() + '<br>' +
                 this.translate.get('alarmingAcked')['value'] + ': ' + (params.data[2] > 0 ? new Date(params.data[2]).toLocaleString() : '-');
        }
      },
      toolbox: {
        show: false,
        feature: {
          saveAsImage: {show: true, type: 'png'}
        }
      },
      calculable: false,
      grid: {
        x: '90',
        y: '20',
        x2: '20',
        y2: '0',
        containLabel: true
      },
      xAxis: {
        type: 'time',
        boundaryGap: false,
      },
      yAxis: {
        type : 'value',
        splitArea: {show: true},
        name: '',
        axisLabel: {}
      },
      series: [{
        type: 'scatter',
        symbolSize: '10',
        showSymbol: false,
        markLine: {
          itemStyle: {
            normal: {
              lineStyle: {
                type: 'dashed',
                color: 'darkred'
              }
            }
          }
        },
        data: []
      }]
    };

    const bSubtext = this.translate.get('heartUnit')['value'];
    this.bchartOptions = _.cloneDeep(options);
    this.bchartOptions.title.text = this.translate.get('breathe')['value'];
    this.bchartOptions.title.subtext = bSubtext;
    this.bchartOptions.series[0].type = 'line';
    this.bchartOptions.series[0].markLine.data = [
      {name: 'upper', yAxis: this.person.breatheUp},
      {name: 'lower', yAxis: this.person.breatheLow},
    ];
    this.bchartOptions.tooltip.trigger = 'axis';
    this.bchartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + bSubtext;
    };

    this.hchartOptions = _.cloneDeep(options);
    this.hchartOptions.title.text = this.translate.get('heart')['value'];
    this.hchartOptions.title.subtext = bSubtext;
    this.hchartOptions.series[0].type = 'line';
    this.hchartOptions.series[0].markLine.data = [
      {name: 'upper', yAxis: this.person.heartUp},
      {name: 'lower', yAxis: this.person.heartLow},
    ];
    this.hchartOptions.tooltip.trigger = 'axis';
    this.hchartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + bSubtext;
    };

    const moveSubtext = this.translate.get('alarmUnit')['value'] + '/' + this.translate.get('hour')['value'];
    this.moveChartOptions = _.cloneDeep(options);
    this.moveChartOptions.title.text = this.translate.get('move')['value'];
    this.moveChartOptions.title.subtext = moveSubtext;
    this.moveChartOptions.tooltip.trigger = 'axis';
    this.moveChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + moveSubtext;
    };
    this.moveChartOptions.series[0].type = 'bar';
    this.moveChartOptions.series[0].barMaxWidth = '12px';
    this.moveChartOptions.series[0].markLine.data = [{ yAxis: this.person.move}];

    this.awayAlarmChartOptions = _.cloneDeep(options);
    this.awayAlarmChartOptions.title.text = this.translate.get('awayAlarm')['value'];
    this.awayAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      // return this.translate.get('AWAY')['value'];
      return '';
    };

    this.sideAlarmChartOptions = _.cloneDeep(options);
    this.sideAlarmChartOptions.title.text = this.translate.get('sideAlarm')['value'];
    this.sideAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      // return this.translate.get('SIDE')['value'];
      return '';
    };

    this.upAlarmChartOptions = _.cloneDeep(options);
    this.upAlarmChartOptions.title.text = this.translate.get('upAlarm')['value'];
    this.upAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      // return this.translate.get('UP')['value'];
      return '';
    };

    this.breatheAlarmChartOptions = _.cloneDeep(options);
    this.breatheAlarmChartOptions.title.text = this.translate.get('breatheAlarm')['value'];
    /*
    this.breatheAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      return this.translate.get('BREATHE')['value'];
    };
    */
    this.breatheAlarmChartOptions.tooltip.formatter = (params) => {
      return this.translate.get('alarmingStarts')['value'] + ': ' + new Date(params.data[0]).toLocaleString() + '<br>' +
             this.translate.get('breathe')['value'] + ': ' + params.data[1] + bSubtext + '<br>' +
             this.translate.get('alarmingAcked')['value'] + ': ' + (params.data[2] > 0 ? new Date(params.data[2]).toLocaleString() : '-');
    };

    this.heartAlarmChartOptions = _.cloneDeep(options);
    this.heartAlarmChartOptions.title.text = this.translate.get('heartAlarm')['value'];
    /*
    this.heartAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      return this.translate.get('HEART')['value'];
    };
    */
    this.heartAlarmChartOptions.tooltip.formatter = (params) => {
      return this.translate.get('alarmingStarts')['value'] + ': ' + new Date(params.data[0]).toLocaleString() + '<br>' +
             this.translate.get('heart')['value'] + ': ' + params.data[1] + bSubtext + '<br>' +
             this.translate.get('alarmingAcked')['value'] + ': ' + (params.data[2] > 0 ? new Date(params.data[2]).toLocaleString() : '-');
    };

    this.wetAlarmChartOptions = _.cloneDeep(options);
    this.wetAlarmChartOptions.title.text = this.translate.get('wetAlarm')['value'];
    this.wetAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      // return this.translate.get('WET')['value'];
      return '';
    };

    this.turnOverAlarmChartOptions = _.cloneDeep(options);
    this.turnOverAlarmChartOptions.title.text = this.translate.get('turnOverAlarm')['value'];
    this.turnOverAlarmChartOptions.title.subtext = '';
    this.turnOverAlarmChartOptions.tooltip.formatter = (params) => {
      const label = this.translate.get(params.data[1] === 1 ? 'LEFT' : 'RIGHT')['value'];
      return new Date(params.data[0]).toLocaleString() + '<br>' + label;
    };
    this.turnOverAlarmChartOptions.yAxis.data = [1, 2];
    this.turnOverAlarmChartOptions.yAxis.axisLabel.formatter = (value) => {
      if (value === 1) {
        return this.translate.get('LEFT')['value'];
      }

      if (value === 2) {
        return this.translate.get('RIGHT')['value'];
      }

      return '';
    };

    this.sleepChartOptions = _.cloneDeep(options);
    this.sleepChartOptions.title.text = this.translate.get('sleep')['value'];
    this.sleepChartOptions.title.subtext = this.translate.get('hour')['value'];
    this.sleepChartOptions.tooltip.trigger = 'axis';
    this.sleepChartOptions.tooltip.formatter = null;
    this.sleepChartOptions.legend = { data: [this.translate.get('sleepHeavy')['value'], this.translate.get('sleepLight')['value'], this.translate.get('sleepAwake')['value']] };
    this.sleepChartOptions.xAxis = [{ type: 'category', data: [] }];
    this.sleepChartOptions.yAxis = [{ type: 'value' }];
    this.sleepChartOptions.series = [{
        name: this.translate.get('sleepHeavy')['value'],
        type: 'bar',
        stack: 'sleep',
        barMaxWidth: 20,
        data: []
      }, {
        name: this.translate.get('sleepLight')['value'],
        type: 'bar',
        stack: 'sleep',
        barMaxWidth: 20,
        data: []
      }];
  }

  onhChartInit(ec) {
    this.hechartsInstance = ec;
    this.hechartsInstance.setOption(this.hchartOptions);
  }

  onbChartInit(ec) {
    this.bechartsInstance = ec;
    this.bechartsInstance.setOption(this.bchartOptions);
  }

  onMoveChartInit(ec) {
    this.moveChartsInstance = ec;
    this.moveChartsInstance.setOption(this.moveChartOptions);
  }

  onAwayAlarmChartInit(ec) {
    this.awayAlarmChartsInstance = ec;
    this.awayAlarmChartsInstance.setOption(this.awayAlarmChartOptions);
  }

  onSideAlarmChartInit(ec) {
    this.sideAlarmChartsInstance = ec;
    this.sideAlarmChartsInstance.setOption(this.sideAlarmChartOptions);
  }

  onUpAlarmChartInit(ec) {
    this.upAlarmChartsInstance = ec;
    this.upAlarmChartsInstance.setOption(this.upAlarmChartOptions);
  }

  onBreatheAlarmChartInit(ec) {
    this.breatheAlarmChartsInstance = ec;
    this.breatheAlarmChartsInstance.setOption(this.breatheAlarmChartOptions);
  }

  onHeartAlarmChartInit(ec) {
    this.heartAlarmChartsInstance = ec;
    this.heartAlarmChartsInstance.setOption(this.heartAlarmChartOptions);
  }

  onWetAlarmChartInit(ec) {
    this.wetAlarmChartsInstance = ec;
    this.wetAlarmChartsInstance.setOption(this.wetAlarmChartOptions);
  }

  onTurnOverAlarmChartInit(ec) {
    this.turnOverAlarmChartsInstance = ec;
    this.turnOverAlarmChartsInstance.setOption(this.turnOverAlarmChartOptions);
  }

  onSleepChartInit(ec) {
    this.sleepChartsInstance = ec;
    this.sleepChartsInstance.setOption(this.sleepChartOptions);
  }

  buildEmptyData(startTime, endTime) {
    const data = [[startTime * 1000, ''], [endTime * 1000, '']];
    return data;
  }

  refresh() {
    let startTime = this.fromTimeCtrl.value ? this.fromTimeCtrl.value.setHours(0, 0, 0, 0) : null;
    let endTime = this.toTimeCtrl.value ? this.toTimeCtrl.value.setHours(23, 59, 59, 999) : null;

    if (!startTime) {
      this.error = 'noStartTime';
      return;
    }

    const currentTime = new Date().getTime();
    if (startTime > currentTime) {
      this.error = 'lateStartTime'
      return;
    }

    if ( !endTime || endTime > currentTime) {
      endTime = currentTime;
    }

    if (endTime < startTime) {
      this.error = 'startTimeGreaterThanEndTime'
      return;
    }

    this.error = '';

    startTime = Math.round(startTime / 1000);
    endTime = Math.round(endTime / 1000);

    this.processType(startTime, endTime, 'HIST_MOVE', this.moveChartsInstance, this.moveChartOptions);
    this.processType(startTime, endTime, 'HIST_BREATHE', this.bechartsInstance, this.bchartOptions);
    this.processType(startTime, endTime, 'HIST_HEART', this.hechartsInstance, this.hchartOptions);

    this.processType(startTime, endTime, 'AWAY', this.awayAlarmChartsInstance, this.awayAlarmChartOptions);
    this.processType(startTime, endTime, 'SIDE', this.sideAlarmChartsInstance, this.sideAlarmChartOptions);
    this.processType(startTime, endTime, 'UP', this.upAlarmChartsInstance, this.upAlarmChartOptions);
    this.processType(startTime, endTime, 'BREATHE', this.breatheAlarmChartsInstance, this.breatheAlarmChartOptions);
    this.processType(startTime, endTime, 'HEART', this.heartAlarmChartsInstance, this.heartAlarmChartOptions);
    this.processType(startTime, endTime, 'WET', this.wetAlarmChartsInstance, this.wetAlarmChartOptions);

    this.processTurnOver(startTime, endTime);
    this.processSleep(startTime, endTime);
  }

  processType(startTime, endTime, alarm, chartInstance, chartOptions) {
    const type = this.rest.getAlarmEnumNumber(alarm);

    this.rest.getWithParams('api/elastic/typeInRange', {
      personId: this.person.id,
      startTime: startTime,
      endTime: endTime,
      type: type
    }).subscribe(resp => {
      let data: any = resp;
      if (data && data.length > 0) {
        if (data[0][0] !== startTime * 1000) {
          data.unshift([startTime * 1000, '']);
        }

        if (data[data.length - 1][0] !== endTime * 1000) {
          data.push([endTime * 1000, '']);
        }
      } else {
        data = this.buildEmptyData(startTime, endTime);
      }

      chartOptions.series[0].data = data;
      chartInstance.setOption(chartOptions);
    });
  }

  processTurnOver(startTime, endTime) {
    this.rest.getWithParams('api/elastic/turnOverInRange', {
      personId: this.person.id,
      startTime: startTime,
      endTime: endTime
    }).subscribe(resp => {
      let data: any = resp;
      if (data && data.length > 0) {
        if (data[0][0] !== startTime * 1000) {
          data.unshift([startTime * 1000, '']);
        }

        if (data[data.length - 1][0] !== endTime * 1000) {
          data.push([endTime * 1000, '']);
        }
      } else {
        data = this.buildEmptyData(startTime, endTime);
      }

      this.turnOverAlarmChartOptions.series[0].data = data;
      this.turnOverAlarmChartsInstance.setOption(this.turnOverAlarmChartOptions);
    });
  }

  processSleep(startTime, endTime) {
    this.rest.getWithParams('api/elastic/sleepInRange', {
      personId: this.person.id,
      startTime: startTime,
      endTime: endTime
    }).subscribe(resp => {
      const data: any = resp;
      if (!data || data.length === 0) {
        const startDate = new Date(startTime * 1000).toLocaleDateString();
        const endDate = new Date(endTime * 1000).toLocaleDateString();
        const categ = [startDate];
        if (startDate !== endDate) {
          categ.push(endDate);
        }
        this.sleepChartOptions.xAxis[0].data = categ;
        this.sleepChartsInstance.setOption(this.sleepChartOptions);
        return;
      }

      const heavy = [];
      const light = [];
      const category = [];
      data.forEach(item => {
        category.push(new Date(item[0]).toLocaleDateString());
        if (item[1] === '') {
          heavy.push('');
          light.push('');
        } else {
          const hValue = Math.floor((item[1] / 36.0)) / 100.0;
          const lValue = Math.floor((item[2] / 36.0)) / 100.0;
          heavy.push(hValue);
          light.push(lValue);
        }
      });

      this.sleepChartOptions.series[0].data = heavy;
      this.sleepChartOptions.series[1].data = light;
      this.sleepChartOptions.xAxis[0].data = category;
      this.sleepChartsInstance.setOption(this.sleepChartOptions);
    });
  }

  resizeChart() {
    if (this.hechartsInstance) {
      this.hechartsInstance.resize();
    }

    if (this.bechartsInstance) {
      this.bechartsInstance.resize();
    }

    if (this.moveChartsInstance) {
      this.moveChartsInstance.resize();
    }

    if (this.awayAlarmChartsInstance) {
      this.awayAlarmChartsInstance.resize();
    }

    if (this.sideAlarmChartsInstance) {
      this.sideAlarmChartsInstance.resize();
    }

    if (this.upAlarmChartsInstance) {
      this.upAlarmChartsInstance.resize();
    }

    if (this.breatheAlarmChartsInstance) {
      this.breatheAlarmChartsInstance.resize();
    }

    if (this.heartAlarmChartsInstance) {
      this.heartAlarmChartsInstance.resize();
    }

    if (this.wetAlarmChartsInstance) {
      this.wetAlarmChartsInstance.resize();
    }

    if (this.turnOverAlarmChartsInstance) {
      this.turnOverAlarmChartsInstance.resize();
    }

    if (this.sleepChartsInstance) {
      this.sleepChartsInstance.resize();
    }
  }

  ngOnInit() {
    setTimeout(() => {
      this.refresh();
    }, 1000);
  }
}
